home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / The World of Computer Software.iso / tags18.zip / ASMTAG.E < prev    next >
Text File  |  1992-03-29  |  26KB  |  776 lines

  1. /*
  2.  EPSHeader
  3.  
  4.    File: asmtag.c
  5.    Author: J. Kercheval
  6.    Created: Sun, 07/14/1991  17:25:26
  7. */
  8. /*
  9.  EPSRevision History
  10.  
  11.    J. Kercheval  Sun, 07/14/1991  20:25:59  creation
  12.    J. Kercheval  Mon, 07/15/1991  22:47:30  finish finite state machine parser
  13.    J. Kercheval  Wed, 07/17/1991  21:35:43  add IsMember() and get_token()
  14.    J. Kercheval  Thu, 07/18/1991  19:57:34  add flags checking
  15.    J. Kercheval  Sun, 07/21/1991  15:58:56  add comment block support
  16.    J. Kercheval  Sat, 07/27/1991  21:16:53  remove public post process support
  17.    J. Kercheval  Sat, 07/27/1991  22:50:49  performance considerations (+10%)
  18.    J. Kercheval  Sat, 08/10/1991  18:14:46  Speed up IsMember()
  19.    J. Kercheval  Fri, 09/13/1991  01:17:05  add when_loading() to remap def_srch_case_map[]
  20.    J. Kercheval  Thu, 10/03/1991  12:27:37  fix logic outputting local labels
  21.    J. Kercheval  Sat, 10/05/1991  14:06:33  add ASMTagWant defines
  22. */
  23.  
  24. /*
  25.  * This file implements tagging for .ASM and .INC files which contain 80x86
  26.  * assembler in the MASM/TASM syntax.  This file defines no new commands and
  27.  * is intended to work with the tags package included with V5.0 of Epsilon.
  28.  * There is no problem using modified tags packages providing calls are made
  29.  * to tags_suffix_???() routines in the same way Epsilon does this and that
  30.  * an output routine add_tag() is used.  All that should be required is to
  31.  * compile and load this file and this module will be used transparently to
  32.  * you.
  33.  *
  34.  * This module implements tagging for UNION, STRUC, MACRO, PROC, LABEL
  35.  * keywords as well as for implicit labels (label:) and for data defintions
  36.  * (ie. equ, =, dq, dw, db, etc....).  The performance cost on a per tag
  37.  * basis is negligable, but since more tagging is done, you should expect a
  38.  * practical 10%-20% performance hit on a per file basis.  This tagger is not
  39.  * intended to do all of your work for you but is designed to be used in
  40.  * conjunction with the tags generator I have developed and is now available.
  41.  * This file implements the same semantic parser as is found in that
  42.  * executable.  Use the executable in your make file for very fast and
  43.  * updated tags.  If you have problems finding it, contact me and I can point
  44.  * the way...
  45.  *
  46.  * There is defined at the end of this module a when_loading() function which
  47.  * alters the default search case map to allow *correct* (or at least
  48.  * consistent sorting with sort routines external to Epsilon.  In particular,
  49.  * to produce the same sort order as any UNIX, VMS or HP style sort or with
  50.  * the tags generator this module is supposed to coexist with this mapping
  51.  * must be done.  You should see no difference in the location of sorted
  52.  * buffers except for lines starting with ^, [, \, ] and _.
  53.  *
  54.  * This code is dedicated to the public domain with the caveat that Lugaru is
  55.  * welcome to use this within their distribution source code which is
  56.  * supplied with Epsilon.
  57.  *
  58.  * Good Tagging,
  59.  *
  60.  *      jbk@wrq.com
  61.  *
  62.  *      John Kercheval
  63.  *      127 NW Bowdoin Pl #105
  64.  *      Seattle, WA  98107-4960
  65.  *      August 10, 1991
  66.  */
  67.  
  68. #include <eel.h>
  69.  
  70. #ifndef BOOLEAN
  71. #define BOOLEAN int
  72. #define TRUE 1
  73. #define FALSE 0
  74. #endif
  75.  
  76. /* This is a list of the types of tokens you may want to tag.  Set them true
  77.  * if you want that particular type of tag. 
  78.  */
  79. #define ASMTagWantProc TRUE
  80. #define ASMTagWantMacro TRUE
  81. #define ASMTagWantLabel TRUE
  82. #define ASMTagWantStruc TRUE
  83. #define ASMTagWantUnion TRUE
  84. #define ASMTagWantDefine TRUE
  85.  
  86. /*
  87.  * The finite state machine allows the following interesting paths
  88.  *
  89.  *    1 - Discard, Parse1, Symbol1
  90.  *    2 - Discard, Parse1, Parse2, Symbol2
  91.  *    3 - Discard, Parse1, Parse2, Define
  92.  *
  93.  * all the important cases follow one of these paths according to MASM/TASM
  94.  * syntax.  The exit state is for finish up routine calls and some paths not
  95.  * covered here are simple error paths and probably result from syntax errors
  96.  *
  97.  *  enum state { Discard, Parse1, Parse2, Symbol1, Symbol2, Define, Exit };
  98.  */
  99. /*
  100.  * emulate an enumerated type for the state machine
  101.  */
  102.  
  103. #define Discard 0
  104. #define Parse1  1
  105. #define Parse2  2
  106. #define Symbol1 3
  107. #define Symbol2 4
  108. #define Define  5
  109. #define Exit    6
  110.  
  111. typedef int State;
  112.  
  113. #define COMMENT_CHAR ';'
  114.  
  115. #define SYMBOL_SIZE 15
  116.  
  117.  
  118. /*----------------------------------------------------------------------------
  119.  *
  120.  * The symbol lists represent all the symbols we are interested in either
  121.  * obtaining or ignoring.  The first element of each of these symbol lists is
  122.  * a string containing all the first characters within the symbol list.  This
  123.  * allows faster rejection for IsMember() which is called often.
  124.  *
  125.  ---------------------------------------------------------------------------*/
  126.  
  127. /* symbols which are not significant for this parser */
  128. char ASM_NOP_Sym[][SYMBOL_SIZE] =
  129. {
  130.     "cpbfnwo",                  /* list of starting characters of symbols
  131.                                  * below */
  132.     "c",                        /* C language declaration */
  133.     "pascal",                   /* PASCAL language declaration */
  134.     "basic",                    /* BASIC language declaration */
  135.     "fortran",                  /* FORTRAN language declaration */
  136.     "prolog",                   /* PROLOG language declaration */
  137.     "nolanguage",               /* generic language declaration */
  138.     "windows",                  /* WINDOWS exit and entry modifier */
  139.     "oddnear",                  /* overlay modifier */
  140.     "oddfar",                   /* overlay modifier */
  141.     "normal",                   /* normal procedure entry/exit code */
  142.     "\0"
  143. };
  144.  
  145. /* symbols which begin a comment block */
  146. char ASM_comment_block[][SYMBOL_SIZE] =
  147. {
  148.     "c",                        /* list of starting characters of symbols
  149.                                  * below */
  150.     "comment",                  /* begin comment block, next character is
  151.                                  * delimiter */
  152.     "\0"
  153. };
  154.  
  155.  
  156. /* create the function for determining if a character is a delimiter */
  157. #define IsDelim(c) ( _ASM_delim_table[c] )
  158.  
  159. /* the indexed table for white space character lookup */
  160. BOOLEAN _ASM_delim_table[256];
  161.  
  162. /* valid delimiters for this syntax */
  163. char ASM_delim[] = " \t\n;:=.,\"()<>[]*-+/";
  164.  
  165.  
  166. /* create the function for determining if a character is a whitespace */
  167. #define IsWhite(c) ( _ASM_white_table[c] )
  168.  
  169. /* the indexed table for white space character lookup */
  170. BOOLEAN _ASM_white_table[256];
  171.  
  172. /* whitespace characters */
  173. char ASM_white[] = " \t\v\f";
  174.  
  175.  
  176. /* symbols which both are delimiters and a special token, these are
  177.     special tokens only when found at the the beginning of a string of
  178.     1 or more delimiters */
  179. char ASM_delim_Sym[] = "=:";
  180.  
  181. /* symbols which fit into the Define state and represent a tagged symbol */
  182. /* state Define depends on the token ":" being at index 1 in this list */
  183. char ASM_def[][SYMBOL_SIZE] =
  184. {
  185.     ":e=cd",                    /* list of starting characters of symbols
  186.                                  * below */
  187.     ":",                        /* local labels */
  188.     "equ",                      /* equivalence */
  189.     "=",                        /* equivalence */
  190.     "catstr",                   /* concatenated and named strings */
  191.     "db",                       /* named byte data definition */
  192.     "dw",                       /* named word data definition */
  193.     "dd",                       /* named double word data definition */
  194.     "dp",                       /* named 6 byte far pointer data area
  195.                                  * definition */
  196.     "df",                       /* named 6 byte far pointer definition */
  197.     "dq",                       /* named quad word data definition */
  198.     "dt",                       /* named 10 byte data area */
  199.     "\0"
  200. };
  201.  
  202. /* symbols which fit into the Symbol state and represent a tagged symbol */
  203. char ASM_sym[][SYMBOL_SIZE] =
  204. {
  205.     "pmlsu",                    /* list of starting character of symbols
  206.                                  * below */
  207.     "proc",                     /* procedures */
  208.     "macro",                    /* macros */
  209.     "label",                    /* local labels */
  210.     "struc",                    /* structures */
  211.     "union",                    /* unions */
  212.     "\0"
  213. };
  214.  
  215.  
  216. /*----------------------------------------------------------------------------
  217.  *
  218.  * ASMParserInit() initializes the tables required by the parser The tables
  219.  * used are a simple boolean index which are true if the character
  220.  * corresponding to the index is a member of the associated table.
  221.  *
  222.  ---------------------------------------------------------------------------*/
  223.  
  224. ASMParserInit()
  225. {
  226.     char *s;
  227.     int i;
  228.  
  229.     /* init the entire block to FALSE */
  230.     for (i = 0; i < 256; i++) {
  231.         _ASM_delim_table[i] = FALSE;
  232.         _ASM_white_table[i] = FALSE;
  233.     }
  234.  
  235.     /* set the characters in the delim set to TRUE */
  236.     for (s = ASM_delim; *s; s++) {
  237.         _ASM_delim_table[*s] = TRUE;
  238.     }
  239.  
  240.     /* NULL is also a delimiter */
  241.     _ASM_delim_table['\0'] = TRUE;
  242.  
  243.     /* set the characters in the white set to TRUE */
  244.     for (s = ASM_white; *s; s++) {
  245.         _ASM_white_table[*s] = TRUE;
  246.     }
  247. }
  248.  
  249.  
  250. /*----------------------------------------------------------------------------
  251.  *
  252.  * strchr() is the standard string library function strchr()
  253.  *
  254.  ---------------------------------------------------------------------------*/
  255.  
  256. char *strchr(s, c)
  257.     char *s;
  258.     char c;
  259. {
  260.     char *ret = s;
  261.  
  262.     while (*ret) {
  263.         if (*ret == c)
  264.             return ret;
  265.         ret++;
  266.     }
  267.  
  268.     if (*ret == c)
  269.         return ret;
  270.  
  271.     return NULL;
  272. }
  273.  
  274.  
  275. /*----------------------------------------------------------------------------
  276.  *
  277.  * ASMSymbolWanted() returns true if the index into the sym token list is one
  278.  * of the wanted symbols according to the ASMTagWant defines.  The indexes 
  279.  * belong with the following ASMTagWant defines:
  280.  *
  281.  *          Flag             Symbol   Index
  282.  *          ---------------  -------  -----
  283.  *          ASMTagWantProc   "proc"   1
  284.  *          ASMTagWantMacro  "macro"  2
  285.  *          ASMTagWantLabel  "label"  3
  286.  *          ASMTagWantStruc  "struc"  4
  287.  *          ASMTagWantUnion  "union"  5
  288.  *
  289.  ---------------------------------------------------------------------------*/
  290.  
  291. BOOLEAN ASMSymbolWanted(index)
  292.     int index;
  293. {
  294.     /* return true if the associated flag is true */
  295.     switch (index) {
  296.         case 1:
  297.             return ASMTagWantProc;
  298.             break;
  299.         case 2:
  300.             return ASMTagWantMacro;
  301.             break;
  302.         case 3:
  303.             return ASMTagWantLabel;
  304.             break;
  305.         case 4:
  306.             return ASMTagWantStruc;
  307.             break;
  308.         case 5:
  309.             return ASMTagWantUnion;
  310.             break;
  311.         default:
  312.             return FALSE;
  313.             break;
  314.     }
  315. }
  316.  
  317.  
  318. /*----------------------------------------------------------------------------
  319.  *
  320.  * ASMIsMember() takes the token passed and check for membership in the null
  321.  * terminated array, tokenlist, and return TRUE if a member and FALSE
  322.  * otherwise, index is the index into the token list of the symbol if return
  323.  * value is TRUE
  324.  *
  325.  ---------------------------------------------------------------------------*/
  326.  
  327. BOOLEAN ASMIsMember(token_list, token, index)
  328.     char token_list[][SYMBOL_SIZE];
  329.     char *token;
  330.     int *index;
  331. {
  332.     int old_case_fold = case_fold;
  333.  
  334.     /* use non case sensitive string compare */
  335.     case_fold = 1;
  336.  
  337.     /* look for dirty rejection */
  338.     if (!strchr(token_list[0], tolower(token[0])))
  339.         return FALSE;
  340.  
  341.     /* march through array until membership is determined */
  342.     for (*index = 1; *token_list[*index]; (*index)++) {
  343.  
  344.         /* return true if token found */
  345.         if (!strfcmp(token, token_list[*index])) {
  346.             case_fold = old_case_fold;
  347.             return TRUE;
  348.         }
  349.     }
  350.  
  351.     /* did not find it */
  352.     case_fold = old_case_fold;
  353.     return FALSE;
  354. }
  355.  
  356.  
  357. /*----------------------------------------------------------------------------
  358.  *
  359.  * ASM_get_token() will obtain the next token in the line pointed to by lptr
  360.  * and in addition will return FALSE if EOL is reached or a comment character
  361.  * is the first non whitespace character found
  362.  *
  363.  ---------------------------------------------------------------------------*/
  364.  
  365. BOOLEAN ASM_get_token(lptr, token)
  366.     char **lptr;
  367.     char *token;
  368. {
  369.     char *s;                    /* start location in string */
  370.     int token_length;           /* the length of the current token */
  371.     int dummy;                  /* a temporary variable */
  372.  
  373.     /* loop until we have a valid token or end of string */
  374.     do {
  375.         /* move past whitespace */
  376.         while (IsWhite(**lptr)) {
  377.             (*lptr)++;
  378.         }
  379.  
  380.         /* return false if end of line */
  381.         if (!**lptr)
  382.             return FALSE;
  383.  
  384.         /* check if comment */
  385.         if (**lptr == COMMENT_CHAR) {
  386.             return FALSE;
  387.         }
  388.  
  389.         /* check of delimiter token */
  390.         if (strchr(ASM_delim_Sym, **lptr)) {
  391.             token[0] = **lptr;
  392.             token[1] = '\0';
  393.             (*lptr)++;
  394.         }
  395.         else {
  396.  
  397.             /* save the beginning location */
  398.             s = *lptr;
  399.  
  400.             /* move to the next delimiter in the line */
  401.             while (!IsDelim(**lptr)) {
  402.                 (*lptr)++;
  403.             }
  404.  
  405.             /* get the token */
  406.             token_length = *lptr - s;
  407.             strncpy(token, s, token_length);
  408.             token[token_length] = '\0';
  409.         }
  410.  
  411.     } while (ASMIsMember(ASM_NOP_Sym, token, &dummy));
  412.  
  413.     return TRUE;
  414. }
  415.  
  416.  
  417. /*----------------------------------------------------------------------------
  418.  *
  419.  * getline() obtain the next line in the buffer
  420.  *
  421.  ---------------------------------------------------------------------------*/
  422.  
  423. BOOLEAN getline(inbuf, line)
  424.     char *inbuf;
  425.     char *line;
  426. {
  427.     char *oldbuf = bufname;
  428.     int cur_point = point;
  429.  
  430.     bufname = inbuf;
  431.  
  432.     nl_forward();
  433.     if (cur_point != point) {
  434.         grab(cur_point, point, line);
  435.     }
  436.     else {
  437.         return FALSE;
  438.     }
  439.  
  440.     bufname = oldbuf;
  441.     return TRUE;
  442. }
  443.  
  444.  
  445. /*----------------------------------------------------------------------------
  446.  *
  447.  * output_tag() places the tag in the correct format into the output buffer
  448.  * by a call to add_tag()
  449.  *
  450.  ---------------------------------------------------------------------------*/
  451.  
  452. output_tag(outbuf, line, symbol, infname, line_number, char_number)
  453.     char *outbuf;
  454.     char *line;
  455.     char *symbol;
  456.     char *infname;
  457.     int line_number;
  458.     int char_number;
  459. {
  460.     /* this is just a shell call to add_tag() defined in tags.e but is an
  461.      * ideal place to add code for other output formats or extra output
  462.      * information etc. */
  463.     add_tag(symbol, char_number);
  464.     return;
  465. }
  466.  
  467.  
  468. /*----------------------------------------------------------------------------
  469.  *
  470.  * ASMtags() tags an input stream assuming input format of ASM 80x86 format
  471.  * in MASM/TASM syntax
  472.  *
  473.  ---------------------------------------------------------------------------*/
  474.  
  475. ASMTags(inbuf, infname, outbuf)
  476.     char *inbuf;
  477.     char *infname;
  478.     char *outbuf;
  479. {
  480.     State state;                /* the current state of the parser */
  481.  
  482.     char line[256];             /* the current input line */
  483.     char cur_token[256];        /* the current token */
  484.     char prev_token[256];       /* the previous token */
  485.  
  486.     char *lptr;                 /* pointer into line for token parser */
  487.     char *prev_lptr;            /* pointer into line for previous token */
  488.  
  489.     int line_number;            /* the current line in the file */
  490.     int line_length;            /* the length of the current line */
  491.     int char_number;            /* the current character in the file */
  492.  
  493.     int symbol_index;           /* the index into the token list of the
  494.                                  * symbol */
  495.  
  496.     char *oldbuf = bufname;
  497.     spot oldpoint = alloc_spot();
  498.     spot oldmark = alloc_spot();
  499.  
  500.     /* save current buffer state */
  501.     *oldpoint = point;
  502.     *oldmark = mark;
  503.  
  504.     /* init the engine */
  505.     ASMParserInit();
  506.     cur_token[0] = '\0';
  507.     prev_token[0] = '\0';
  508.     state = Discard;
  509.     line_number = 0;
  510.     line_length = 0;
  511.     char_number = 0;
  512.     lptr = prev_lptr = (char *) NULL;
  513.  
  514.     for (;;) {
  515.  
  516.         switch (state) {
  517.  
  518.             case Discard:       /* current line is not valid */
  519.  
  520.                 /* if EOF then return */
  521.                 if (getline(inbuf, line)) {
  522.                     lptr = line;
  523.  
  524.                     /* increment counters */
  525.                     line_number++;
  526.  
  527.                     /* char_number increments by length of previous line */
  528.                     char_number += line_length;
  529.  
  530.                     /* line length */
  531.                     line_length = strlen(line);
  532.                     state = Parse1;
  533.                 }
  534.                 else {
  535.                     state = Exit;
  536.                 }
  537.                 break;
  538.  
  539.             case Parse1:        /* parsing for first *special* token */
  540.  
  541.                 /* get the next valid token */
  542.                 if (!ASM_get_token(&lptr, cur_token)) {
  543.  
  544.                     /* if no token left or a comment as first non white space
  545.                      * char in remainder of line */
  546.                     state = Discard;
  547.                 }
  548.                 else {
  549.  
  550.                     /* move the cur_token to prev_token */
  551.                     strcpy(prev_token, cur_token);
  552.  
  553.                     /* check for membership in the tagging symbol club */
  554.                     if (ASMIsMember(ASM_sym, cur_token, &symbol_index)) {
  555.                         state = Symbol1;
  556.                     }
  557.                     else {
  558.  
  559.                         /* check if comment block */
  560.                         if (ASMIsMember(ASM_comment_block,
  561.                                         cur_token, &symbol_index)) {
  562.  
  563.                             /* get the next non white character, this makes
  564.                              * the assumption that the delimiter character is
  565.                              * on the same line as the comment symbol. If the
  566.                              * delimiter character is not on the current line
  567.                              * then parsing continues normally on the next
  568.                              * line. */
  569.                             while (IsWhite(*lptr)) {
  570.                                 lptr++;
  571.                             }
  572.  
  573.                             if (*lptr) {
  574.  
  575.                                 /* this is the delimiter character, store it
  576.                                  * and move lptr past it */
  577.                                 *cur_token = *lptr;
  578.                                 lptr++;
  579.  
  580.                                 /* move over comment block, remembering to
  581.                                  * update line info as we go */
  582.                                 while (*lptr != *cur_token) {
  583.  
  584.                                     /* get a new line if end of line */
  585.                                     if (!*lptr) {
  586.                                         if (!getline(inbuf, line)) {
  587.                                             *cur_token = *lptr;
  588.                                         }
  589.                                         else {
  590.                                             lptr = line;
  591.  
  592.                                             /* increment counters */
  593.                                             line_number++;
  594.  
  595.                                             /* char_number increments by
  596.                                              * length of previous line */
  597.                                             char_number += line_length;
  598.  
  599.                                             /* line length */
  600.                                             line_length = strlen(line);
  601.                                         }
  602.                                     }
  603.                                     else {
  604.                                         lptr++;
  605.                                     }
  606.                                 }
  607.                             }
  608.  
  609.                             state = Discard;
  610.                         }
  611.                         else {
  612.  
  613.                             /* nothing special, parse the next symbol */
  614.                             state = Parse2;
  615.                         }
  616.                     }
  617.                 }
  618.                 break;
  619.  
  620.             case Parse2:        /* parsing for second *special* token */
  621.  
  622.                 /* save the previous position */
  623.                 prev_lptr = lptr;
  624.  
  625.                 /* get the next token */
  626.                 if (!ASM_get_token(&lptr, cur_token)) {
  627.  
  628.                     /* no token left, reset machine */
  629.                     state = Discard;
  630.                 }
  631.                 else {
  632.  
  633.                     if (ASMIsMember(ASM_sym, cur_token, &symbol_index)) {
  634.  
  635.                         /* found a major symbol */
  636.                         state = Symbol2;
  637.                     }
  638.                     else {
  639.  
  640.                         if (ASMIsMember(ASM_def, cur_token, &symbol_index)) {
  641.  
  642.                             /* found a defining token */
  643.                             state = Define;
  644.                         }
  645.                         else {
  646.                             state = Discard;
  647.                         }
  648.                     }
  649.                 }
  650.  
  651.                 break;
  652.  
  653.             case Symbol1:       /* next token, ignore if no token found */
  654.  
  655.                 /* get the next symbol and output it */
  656.                 if (ASM_get_token(&lptr, cur_token)) {
  657.  
  658.                     if (ASMSymbolWanted(symbol_index)) {
  659.                         output_tag(outbuf, line, cur_token, infname,
  660.                                    line_number, char_number +
  661.                                    lptr - line -
  662.                                    strlen(cur_token));
  663.                     }
  664.                 }
  665.  
  666.                 /* reset machine */
  667.                 state = Discard;
  668.  
  669.                 break;
  670.  
  671.             case Symbol2:       /* previous token was the wanted symbol */
  672.  
  673.                 /* the previous token is the symbol of interest */
  674.                 if (ASMSymbolWanted(symbol_index)) {
  675.                     output_tag(outbuf, line, prev_token, infname,
  676.                                line_number, char_number +
  677.                                prev_lptr - line -
  678.                                strlen(prev_token));
  679.                 }
  680.  
  681.                 /* reset machine */
  682.                 state = Discard;
  683.  
  684.                 break;
  685.  
  686.             case Define:        /* previous token was the wanted symbol */
  687.  
  688.                 /* the previous token is the symbol of interest */
  689.                 if ((ASMTagWantDefine && symbol_index != 1) ||
  690.                     (ASMTagWantLabel && symbol_index == 1)) {
  691.                     output_tag(outbuf, line, prev_token, infname,
  692.                                line_number, char_number +
  693.                                prev_lptr - line -
  694.                                strlen(prev_token));
  695.                 }
  696.  
  697.                 /* reset machine */
  698.                 state = Discard;
  699.  
  700.                 break;
  701.  
  702.             case Exit:          /* clean it up */
  703.  
  704.                 /* restore original location */
  705.                 bufname = oldbuf;
  706.                 point = *oldpoint;
  707.                 mark = *oldmark;
  708.                 free_spot(oldpoint);
  709.                 free_spot(oldmark);
  710.                 return;
  711.                 break;
  712.  
  713.             default:            /* not reached */
  714.                 break;
  715.         }
  716.     }
  717. }
  718.  
  719. /*----------------------------------------------------------------------------
  720.  *
  721.  * tag_suffix_asm() and tag_suffix_inc() are recognized procedure names
  722.  * to the tags package in Epsilon and will be called automatically when
  723.  * tagging needs to happen for these extensions.  tag_suffix_asm() is a
  724.  * replacement for the routine of the same name defined in tags.e and
  725.  * tag_suffix_inc() is new.
  726.  *
  727.  ---------------------------------------------------------------------------*/
  728.  
  729.  
  730. tag_suffix_asm()
  731. {
  732.     /* the third parameter, the output buffer name is not actually used by
  733.      * anyone but is left here for a time when this information may be
  734.      * needed.  The current algorithm is to let the funtion add_tag() decide
  735.      * the buffer name to send the output to.  As a little more than
  736.      * coincedence, the name used here is the same used in add_tag() defined
  737.      * in tags.e */
  738.     ASMTags(bufname, filename, "-tags");
  739. }
  740.  
  741. tag_suffix_inc()
  742. {
  743.     tag_suffix_asm();
  744. }
  745.  
  746. #ifdef foo
  747. /* rebuild the default character maps */
  748. when_loading()
  749. {
  750. #define UCLC(up, low)   _def_char_class[low] = C_LOWER, \
  751.                         _def_char_class[up] = C_UPPER, \
  752.                         _def_srch_case_map[up] = low, \
  753.                         _def_case_map[low] = up, \
  754.                         _def_case_map[up] = low
  755.  
  756.     int i, j;
  757.  
  758.     for (i = 0; i < 256; i++)
  759.         _def_case_map[i] = _def_srch_case_map[i] = i;
  760.     for (i = 'A', j = 'a'; i <= 'Z'; i++, j++)
  761.         UCLC(i, j);
  762.     for (i = 131; i < 154; i++)
  763.         _def_char_class[i] = C_LOWER;
  764.     for (i = 160; i < 164; i++)
  765.         _def_char_class[i] = C_LOWER;
  766.     UCLC('Ç', 'ç');
  767.     UCLC('Ä', 'ä');
  768.     UCLC('Å', 'å');
  769.     UCLC('É', 'é');
  770.     UCLC('Æ', 'æ');
  771.     UCLC('Ö', 'ö');
  772.     UCLC('Ü', 'ü');
  773.     UCLC('Ñ', 'ñ');
  774. }
  775. #endif
  776.